package com.wwdx.controller.admin;

import com.google.code.kaptcha.Producer;
import com.google.common.collect.Maps;
import com.wwdx.controller.base.BaseController;
import com.wwdx.model.dto.ResultBean;
import com.wwdx.model.upms.UpmsUser;
import com.wwdx.service.upms.UpmsUserServiceI;
import com.wwdx.shiro.GlobalStatic;
import com.wwdx.shiro.SessionUser;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.IncorrectCredentialsException;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.crypto.hash.Md5Hash;
import org.apache.shiro.subject.Subject;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.servlet.ModelAndView;

import javax.annotation.Resource;
import javax.imageio.ImageIO;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

/**
 * @author liguoliang
 * @date 2018-2-3
 */
@Controller
@RequestMapping("/login")
public class WwdxLoginController extends BaseController {

    @Resource
    private Producer producer;
    @Resource
    private UpmsUserServiceI upmsUserService;

    /**
     * 进入登录页面
     */
    @GetMapping("/login")
    public ModelAndView login() {
        return new ModelAndView();
    }

    /**
     * 进入密码修改页面
     */
    @RequestMapping("/updatepwd")
    public ModelAndView updatepwd() {
        return new ModelAndView();
    }

    /**
     * 验证原密码是否正确
     * @param oldpwd 旧密码
     */
    @RequestMapping("/validpwd")
    @ResponseBody
    public Map<String,Object> validpwd(String oldpwd) {
        HashMap<String, Object> map = Maps.newHashMapWithExpectedSize(2);
        UpmsUser upmsUser = upmsUserService.getById(SessionUser.getUserId());
        int hashIterations = GlobalStatic.HASHITERATIONS;
        String md5Pwd = new Md5Hash(oldpwd, upmsUser.getAccount() + upmsUser.getSalt(), hashIterations).toHex();
        boolean result = false;
        if (upmsUser.getPassword().equalsIgnoreCase(md5Pwd)){
            result = true;
        }
        map.put("valid", result);
        return map;
    }

    /**
     * 修改密码
     * @param pwd 密码
     */
    @RequestMapping("/saveupdatepwd")
    public String saveupdatepwd(String pwd) {
        UpmsUser upmsUser = upmsUserService.getById(SessionUser.getUserId());
        int hashIterations = GlobalStatic.HASHITERATIONS;
        String md5Pwd = new Md5Hash(pwd, upmsUser.getAccount() + upmsUser.getSalt(), hashIterations).toHex();
        upmsUser.setPassword(md5Pwd);
        upmsUserService.update(upmsUser);
        //修改成功后退出
        return this.logout();
    }
    
    /**
     * 生成验证码
     */
    @RequestMapping("/getCaptcha")
    public void getCaptcha(HttpSession session,HttpServletResponse response) throws IOException{
        response.setDateHeader("Expires", 0);
        // Set standard HTTP/1.1 no-cache headers.
        response.setHeader("Cache-Control", "no-store, no-cache, must-revalidate");
        // Set IE extended HTTP/1.1 no-cache headers (use addHeader).
        response.addHeader("Cache-Control", "post-check=0, pre-check=0");
        // Set standard HTTP/1.0 no-cache header.
        response.setHeader("Pragma", "no-cache");
        // return a jpeg
        response.setContentType("image/jpeg");
        //生成文字验证码
        String code = producer.createText();
        //生成图片流
        BufferedImage bi = producer.createImage(code);
        session.setAttribute(GlobalStatic.DEFAULT_CAPTCHA_PARAM, code);
        // write the data out
        ImageIO.write(bi, "jpg", response.getOutputStream());
    }

    /**
     * 登录
     * @param captcha 验证码
     * @param upmsUser 用户名和密码
     */
    @PostMapping("/login")
    @ResponseBody
    public ResultBean auth(HttpSession session,boolean rememberMe,String captcha,UpmsUser upmsUser) {
        //系统产生的验证码
        String code = (String) session.getAttribute(GlobalStatic.DEFAULT_CAPTCHA_PARAM);
        session.removeAttribute(GlobalStatic.DEFAULT_CAPTCHA_PARAM);
        //如果验证码不匹配,跳转到登录
        if (!captcha.equalsIgnoreCase(code)) {
            return renderError("验证码错误!");
        }
        //通过账号和密码获取 UsernamePasswordToken token
        UsernamePasswordToken token = new UsernamePasswordToken(upmsUser.getAccount(), upmsUser.getPassword());
        //记住我
        if(rememberMe){
            token.setRememberMe(true);
        }else{
            token.setRememberMe(false);
        }

        try {
            //会调用 shiroDbRealm 的认证方法
            Subject user = SecurityUtils.getSubject();
            user.login(token);
        } catch (UnknownAccountException | IncorrectCredentialsException | LockedAccountException e) {
            logger.error("错误信息：{}",e.getMessage());
            return renderError(e.getMessage());
        } catch (Exception e) {
            logger.error("错误信息：{}",e.getMessage());
            return renderError("未知错误,请联系管理员！");
        }
        return renderSuccess();
    }

    /**
     * 退出,防止csrf
     */
    @RequestMapping("/logout")
    public String logout(){
        Subject subject = SecurityUtils.getSubject();
        if (subject != null) {
            subject.logout();
        }
        return "redirect:/login/login";
    }
}